package cn.jhz.learn.blog.service.security.resource.article.impl;

import cn.jhz.learn.blog.common.exception.ParamException;
import cn.jhz.learn.blog.component.GLOBAL;
import cn.jhz.learn.blog.component.ValidationHolder;
import cn.jhz.learn.blog.dao.article.BlogArticleMapper;
import cn.jhz.learn.blog.dao.article.BlogArticleSubfieldMapper;
import cn.jhz.learn.blog.po.article.BlogArticle;
import cn.jhz.learn.blog.po.article.BlogArticleSubfield;
import cn.jhz.learn.blog.po.blogger.BlogBlogger;
import cn.jhz.learn.blog.service.security.resource.article.ArticleValidationService;
import cn.jhz.learn.blog.service.security.resource.blog.BlogValidationService;

import com.google.common.collect.Lists;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service("articleValidationService")
public class ArticleValidationServiceImpl implements ArticleValidationService {

    private final BlogArticleMapper mapper;
    private final BlogArticleSubfieldMapper subfieldMapper;
    private final BlogValidationService blogValidationService;

    @Autowired
    public ArticleValidationServiceImpl(BlogArticleMapper mapper, BlogArticleSubfieldMapper subfieldMapper, BlogValidationService blogValidationService) {
        this.mapper = mapper;
        this.subfieldMapper = subfieldMapper;
        this.blogValidationService = blogValidationService;
    }

    @Override
    public void valid(Integer id) {
        BlogArticle article =
                (BlogArticle) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE.ID + id);

        if(article == null) {
            article = mapper.selectByPrimaryKey(id);
            if (article == null)
                throw new ParamException("文章不存在!");
            else if(!article.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID))
                throw new ParamException("文章不存在!");
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE.ID + id, article);
        }

        blogValidationService.valid(article.getBlogId());
        switch (article.getVisibility()){
            case 0:
                throw new ParamException("文章未公开!");
            case 1:
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.VISIBILITY + id,
                        Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN));
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.STATUS + id,
                        Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                break;
            case 2:
                throw new ParamException("需订阅文章所属博客!");
            default:
                throw new RuntimeException("数据库记录异常!:" + BlogArticle.class.getName() + ":id:" + id);
        }
    }

    @Override
    public void valid(Integer uid, Integer id) {
        BlogArticle article = (BlogArticle) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE.ID + id);

        if(article == null) {
            article = mapper.selectByPrimaryKey(id);
            if (article == null)
                throw new ParamException("文章不存在!");
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE.ID + id, article);
        }
        blogValidationService.valid(uid, article.getBlogId());
        Byte own =
                (Byte)ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + article.getBlogId());

        if(own.equals(GLOBAL.RESOURCE.OWN_LEVEL.OWN)){
            ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.VISIBILITY + id,
                    Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.ALL));
            ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.STATUS + id,
                    Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID_ALL));
            return ;
        }

        switch (article.getVisibility()){
            case 0:
                throw new ParamException("文章未公开!");
            case 1:
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.VISIBILITY + id,
                        Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN));
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.STATUS + id,
                        Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
            case 2:
                if(own.equals(GLOBAL.RESOURCE.OWN_LEVEL.SUBSCRIBE)){
                    ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.VISIBILITY + id,
                            Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.SUBSCRIBE));
                    ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_ARTICLE.STATUS + id,
                            Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                }else
                    throw new ParamException("文章需要订阅所属博客!");
                break;
            default:
                throw new RuntimeException("数据库记录异常!:" + BlogArticle.class.getName() + ":id:" + id);
        }
    }

    @Override
    public void validStrict(Integer uid, Integer id) {
        BlogArticle article = (BlogArticle) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE.ID + id);
        BlogBlogger user = blogValidationService.uidValid(uid);

        if(article == null){
            article = mapper.selectByPrimaryKey(id);
            if (article == null)
                throw new ParamException("文章不存在!");
            else if (article.getBlogId().equals(user.getId()))
                ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE.ID + id, article);
            else
                throw new ParamException("未拥有该文章!");
        }
    }


    @Override
    public void subfieldValid(Integer subfieldId) {
        BlogArticleSubfield subfield =
                (BlogArticleSubfield) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE_SUBFIELD.ID + subfieldId);

        if(subfield == null) {
            subfield = subfieldMapper.selectByPrimaryKey(subfieldId);
            if (subfield == null)
                throw new ParamException("分支不存在!");
            else if(!subfield.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID))
                throw new ParamException("分支正在维护!");
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE_SUBFIELD.ID + subfieldId, subfield);
        }
        blogValidationService.valid(subfield.getBlogId());

        switch (subfield.getVisibility()){
            case 0:
                throw new ParamException("分支被隐藏!");
            case 1:
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_SUBFIELD.ARTICLES.STATUS + subfieldId,
                        Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_SUBFIELD.ARTICLES.VISIBILITY + subfieldId,
                        Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN));
                break;
            default:
                throw new RuntimeException("数据库记录异常!:" + BlogArticleSubfield.class + ":id:" + subfieldId);
        }
    }

    /**
     * 仅提供有效权限(status==1)
     * @param uid
     * @param subfieldId
     */
    @Override
    public void subfieldValid(Integer uid, Integer subfieldId) {
        BlogArticleSubfield subfield = (BlogArticleSubfield) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE_SUBFIELD.ID + subfieldId);
        BlogBlogger user = blogValidationService.uidValid(uid);

        if(subfield == null) {
            subfield = subfieldMapper.selectByPrimaryKey(subfieldId);
            if (subfield == null)
                throw new ParamException("分支不存在!");
            ValidationHolder.putParam(GLOBAL.VALIDATION_KEY.CLASS_BLOG_ARTICLE_SUBFIELD.ID + subfieldId, subfield);
        }

        blogValidationService.valid(uid, subfield.getBlogId());
        switch ((Byte)ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + subfield.getBlogId())){
            case 0:
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_SUBFIELD.ARTICLES.VISIBILITY + subfieldId, Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.ALL));
                ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_SUBFIELD.ARTICLES.STATUS + subfieldId, Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID_ALL));
                break;
            case 1:
            case 2:
                if(subfield.getStatus().equals(GLOBAL.RESOURCE.STATUS.VALID))
                    if(subfield.getVisibility().equals(GLOBAL.RESOURCE.VISIBILITY.OPEN)){
                        ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_SUBFIELD.ARTICLES.VISIBILITY + subfieldId, Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN));
                        ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_SUBFIELD.ARTICLES.STATUS + subfieldId, Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                    }else
                        throw new ParamException("分支被隐藏!");
                else
                    throw new ParamException("分支不存在!");
                break;
            default:
                throw new RuntimeException("权限字段异常!" + ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + subfield.getBlogId()));
        }
    }

    /**
     * 仅提供有效文章权限(status==1)
     * @param uid
     * @param blogName
     */
    @Override
    public void blogValid(Integer uid, String blogName) {
        BlogBlogger blogger = blogValidationService.valid(uid, blogName);
        switch ((Byte) ValidationHolder.getParam(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.OWN_LEVEL + blogger.getId())){
            case 0:
                ValidationHolder.putLevel(
                        GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.VISIBILITY + blogName,
                        Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.ALL));
                ValidationHolder.putLevel(
                        GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.STATUS + blogName,
                        Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                break;
            case 1:
                ValidationHolder.putLevel(
                        GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.VISIBILITY + blogName,
                        Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN));
                ValidationHolder.putLevel(
                        GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.STATUS + blogName,
                        Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                break;
            case 2:
                ValidationHolder.putLevel(
                        GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.VISIBILITY + blogName,
                        Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN, GLOBAL.RESOURCE.VISIBILITY.SUBSCRIBE));
                ValidationHolder.putLevel(
                        GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.STATUS + blogName,
                        Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
                break;
            default:
                throw new ParamException("OWN_LEVEL异常!:" + BlogBlogger.class.getName() + ":id:" + blogger.getId());
        }
    }

    @Override
    public void blogValid(String blogName) {
        blogValidationService.valid(blogName);
        ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.VISIBILITY + blogName,
                Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.OPEN));
        ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.STATUS  + blogName,
                Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID));
    }

    @Override
    public void blogValid(Integer uid) {
        BlogBlogger user = blogValidationService.uidValid(uid);
        ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.VISIBILITY + user.getId(),
                Lists.newArrayList(GLOBAL.RESOURCE.VISIBILITY.ALL));
        ValidationHolder.putLevel(GLOBAL.VALIDATION_KEY.OWN_ENTITY_BLOG.ARTICLES.STATUS + user.getId(),
                Lists.newArrayList(GLOBAL.RESOURCE.STATUS.VALID_ALL));
    }
}
